<?php
/*
 * @ https://EasyToYou.eu - IonCube v11 Decoder Online
 * @ PHP 7.2 & 7.3
 * @ Decoder version: 1.1.6
 * @ Release: 10/08/2022
 */

// Decoded file for php version 71.
namespace Qcloud\Cos;

class MultipartUpload
{
    private $client;
    private $source;
    private $options;
    private $partSize;
    const MIN_PART_SIZE = 5242880;
    const MAX_PART_SIZE = 1073741824;
    const MAX_PARTS = 10000;
    public function __construct($client, $source, $minPartSize, $options = [])
    {
        $this->client = $client;
        $this->source = $source;
        $this->options = $options;
        $this->partSize = $this->calculatePartSize($minPartSize);
    }
    public function performUploading()
    {
        $uploadId = $this->initiateMultipartUpload();
        $partNumber = 1;
        $parts = [];
        while (true) {
            if($this->source->isConsumed()) {
                break;
            }
            $body = new \Guzzle\Http\ReadLimitEntityBody($this->source, $this->partSize, $this->source->ftell());
            if($body->getContentLength() == 0) {
            } else {
                $result = $this->client->uploadPart(["Bucket" => $this->options["Bucket"], "Key" => $this->options["Key"], "Body" => $body, "UploadId" => $uploadId, "PartNumber" => $partNumber]);
                if(md5($body) != substr($result["ETag"], 1, -1)) {
                    throw new Exception\CosException("ETag check inconsistency");
                }
                $part = ["PartNumber" => $partNumber, "ETag" => $result["ETag"]];
                array_push($parts, $part);
                $partNumber++;
            }
        }
        try {
            $rt = $this->client->completeMultipartUpload(["Bucket" => $this->options["Bucket"], "Key" => $this->options["Key"], "UploadId" => $uploadId, "Parts" => $parts]);
        } catch (\Exception $e) {
            throw $e;
        }
        return $rt;
    }
    public function resumeUploading()
    {
        $uploadId = $this->options["UploadId"];
        $rt = $this->client->ListParts(["UploadId" => $uploadId, "Bucket" => $this->options["Bucket"], "Key" => $this->options["Key"]]);
        $parts = [];
        $offset = $this->partSize;
        if(0 < count($rt["Parts"])) {
            foreach ($rt["Parts"] as $part) {
                $parts[$part["PartNumber"] - 1] = ["PartNumber" => $part["PartNumber"], "ETag" => $part["ETag"]];
            }
        }
        $partNumber = 1;
        while (true) {
            if($this->source->isConsumed()) {
                break;
            }
            $body = new \Guzzle\Http\ReadLimitEntityBody($this->source, $this->partSize, $this->source->ftell());
            if($body->getContentLength() == 0) {
            } else {
                if(array_key_exists($partNumber - 1, $parts)) {
                    if(md5($body) != substr($parts[$partNumber - 1]["ETag"], 1, -1)) {
                        throw new Exception\CosException("ETag check inconsistency");
                    }
                    $body->setOffset($offset);
                } else {
                    $result = $this->client->uploadPart(["Bucket" => $this->options["Bucket"], "Key" => $this->options["Key"], "Body" => $body, "UploadId" => $uploadId, "PartNumber" => $partNumber]);
                    if(md5($body) != substr($result["ETag"], 1, -1)) {
                        throw new Exception\CosException("ETag check inconsistency");
                    }
                    $parts[$partNumber - 1] = ["PartNumber" => $partNumber, "ETag" => $result["ETag"]];
                }
                $partNumber++;
                $offset += $body->getContentLength();
            }
        }
        $rt = $this->client->completeMultipartUpload(["Bucket" => $this->options["Bucket"], "Key" => $this->options["Key"], "UploadId" => $uploadId, "Parts" => $parts]);
        return $rt;
    }
    private function calculatePartSize($minPartSize)
    {
        $partSize = intval(ceil($this->source->getContentLength() / self::MAX_PARTS));
        $partSize = max($minPartSize, $partSize);
        $partSize = min($partSize, self::MAX_PART_SIZE);
        $partSize = max($partSize, self::MIN_PART_SIZE);
        return $partSize;
    }
    private function initiateMultipartUpload()
    {
        $result = $this->client->createMultipartUpload($this->options);
        return $result["UploadId"];
    }
}

?>